From 64d0d8fd51121ff88a8260cd0adabd3c6b0e20ca Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 14 Sep 2005 13:28:45 +0000 Subject: [PATCH] Clear pending interrupt on shared page when pic initialized and irq base changed. Signed-off-by: Yunhong Jiang --- tools/ioemu/hw/i8259.c | 27 ++++++++++++++++----------- xen/arch/x86/vmx_intercept.c | 8 ++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/tools/ioemu/hw/i8259.c b/tools/ioemu/hw/i8259.c index a84e94d44a..06c39fb07c 100644 --- a/tools/ioemu/hw/i8259.c +++ b/tools/ioemu/hw/i8259.c @@ -128,21 +128,23 @@ static int pic_get_irq(PicState *s) /* pic[1] is connected to pin2 of pic[0] */ #define CASCADE_IRQ 2 -static void shared_page_update() +extern shared_iopage_t *shared_page; + +static void xen_update_shared_imr(void) { - extern shared_iopage_t *shared_page; - uint8_t * pmask = (uint8_t *)&(shared_page->sp_global.pic_mask[0]); - int index; + uint8_t *pmask = (uint8_t *)shared_page->sp_global.pic_mask; + int index; index = pics[0].irq_base/8; pmask[index] = pics[0].imr; + index = pics[1].irq_base/8; + pmask[index] = (pics[0].imr & (1 << CASCADE_IRQ)) ? 0xff : pics[1].imr; +} - if ( pics[0].imr & (1 << CASCADE_IRQ) ) { - pmask[index] = 0xff; - } else { - pmask[index] = pics[1].imr; - } +static void xen_clear_shared_irr(void) +{ + memset(shared_page->sp_global.pic_intr, 0, INTR_LEN); } /* raise irq to CPU if necessary. must be called every time the active @@ -174,7 +176,8 @@ static void pic_update_irq(void) #endif cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); } - shared_page_update(); + + xen_update_shared_imr(); } #ifdef DEBUG_IRQ_LATENCY @@ -283,7 +286,9 @@ static void pic_reset(void *opaque) tmp = s->elcr_mask; memset(s, 0, sizeof(PicState)); s->elcr_mask = tmp; - shared_page_update(); + + xen_update_shared_imr(); + xen_clear_shared_irr(); } static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index b329254b36..1f1494c425 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -227,6 +227,7 @@ void vmx_hooks_assist(struct vcpu *d) u64 *intr = &(sp->sp_global.pic_intr[0]); struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit); int rw_mode, reinit = 0; + int oldvec = 0; /* load init count*/ if (p->state == STATE_IORESP_HOOK) { @@ -235,6 +236,7 @@ void vmx_hooks_assist(struct vcpu *d) VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel %lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) ); rem_ac_timer(&(vpit->pit_timer)); reinit = 1; + oldvec = vpit->vector; } else init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, d->processor); @@ -250,6 +252,12 @@ void vmx_hooks_assist(struct vcpu *d) vpit->period = 1000000; } vpit->vector = ((p->u.data >> 16) & 0xFF); + + if( reinit && oldvec != vpit->vector){ + clear_bit(oldvec, intr); + vpit->pending_intr_nr = 0; + } + vpit->channel = ((p->u.data >> 24) & 0x3); vpit->first_injected = 0; -- 2.30.2